package com.wanban.adutils.utils

import android.app.Activity
import android.text.TextUtils
import android.util.Log
import android.view.ViewGroup
import com.wanban.adutils.AdUtils
import com.wanban.adutils.advertisers.BaseAdLoader
import com.wanban.adutils.advertisers.admob.*
import com.wanban.adutils.advertisers.ironsource.ISBannerAdUtils
import com.wanban.adutils.advertisers.ironsource.ISInterstitialAdUtils
import com.wanban.adutils.advertisers.ironsource.ISNativeAdUtils
import com.wanban.adutils.advertisers.ironsource.ISRewardedAdUtils
import com.wanban.adutils.callback.OnLoadAdCallback
import com.wanban.adutils.db.AdRoomUtils
import com.wanban.adutils.db.bean.AdContent
import com.wanban.adutils.db.bean.AdInfo
import com.wanban.adutils.tools.AdConstants
import com.wanban.adutils.tools.RxUtils
import com.wanban.adutils.tools.Tools

class CommonAdTools {

    private var adId: Long? = null
    // 广告请求基类
    private var adLoader: BaseAdLoader? = null

    /**
     * 加载广告，只关注获取AdLoader，执行加载
     */
    fun loadAd(activity: Activity, adId: Long, callback: OnLoadAdCallback){
        this.adId = adId
        val adName = AdUtils.getAdNameByType(adId)
        Log.e(AdConstants.TAG, "$adName -> CommonAdTools -> 开始请求...")
        // 以防万一，先释放广告
        release()
        // 获取广告实体
        val adContent = AdRoomUtils.getInstance().adDao().query(adId)
        if (adContent == null || adContent.adInfo.isNullOrEmpty()) { // 无可用广告
            Log.e(AdConstants.TAG, "$adName -> CommonAdTools ->当前并没有配置 -> $adName")
            callback.onAdLoadFailed(AdConstants.ERROR_CODE_AD_NO_SETTING)
            return
        }
        // 执行广告加载
        excLoadAd(activity, adId, adName, adContent, callback)
    }

    /**
     * 广告是否正在展示
     */
    fun isAdShowing(): Boolean {
        return adLoader?.isAdShowing() ?: false
    }

    fun isAdLoadSuccess(): Boolean {
        return adLoader?.isAdLoadSuccess()?:false
    }

    fun showAdInActivity(activity: Activity){
        if (adLoader?.mOnLoadAdCallback == null) return
        if (adLoader?.isActivityNotActive(activity) == true) {
            adLoader?.mOnLoadAdCallback?.onAdLoadFailed(AdConstants.ERROR_CODE_ACTIVITY_NOT_ACTIVE)
            release()
            return
        }
        adLoader?.showAd(activity)
    }

    /**
     * 展示广告，主要用于banner和native
     */
    fun showAd(adRoot: ViewGroup? = null) {
        if (adLoader?.mOnLoadAdCallback == null) return
        if (adRoot == null) {
            adLoader?.mOnLoadAdCallback?.onAdLoadFailed(AdConstants.ERROR_CODE_ACTIVITY_NOT_ACTIVE)
            adLoader?.destroy()
            return
        }
        val activity = Tools.findActivity(adRoot.context)
        if (activity == null || adLoader?.isActivityNotActive(activity) == true) {
            adLoader?.mOnLoadAdCallback?.onAdLoadFailed(AdConstants.ERROR_CODE_ACTIVITY_NOT_ACTIVE)
            adLoader?.destroy()
            return
        }
        when(adId) {
            AdConstants.AD_ID_OPEN -> adLoader?.showAd(activity)
            AdConstants.AD_ID_OPEN_AD_V2 -> adLoader?.showAd(activity)
            AdConstants.AD_ID_VIDEO_DETAIL_INTERSTITIAL -> adLoader?.showAd(activity)
            AdConstants.AD_ID_VIDEO_DETAIL_PAUSE -> adLoader?.showAd(adRoot, AdConstants.ADTYPE_PAUSE_VIDEO)
            AdConstants.AD_ID_VIDEO_INSTREAM_AD -> adLoader?.showAd(adRoot, AdConstants.ADTYPE_INSTREAM_VIDEO)
            AdConstants.AD_ID_VIDEO_DETAIL_BANNER -> adLoader?.showAd(adRoot, AdConstants.ADTYPE_BANNER)
            AdConstants.AD_ID_LOCK_REWARD_AD -> adLoader?.showAd(activity)
            AdConstants.AD_ID_LOCK_INTERSTITIAL_AD -> adLoader?.showAd(activity)
            AdConstants.AD_ID_DOWNLOAD_REWARD_AD -> adLoader?.showAd(activity)
            AdConstants.AD_ID_DOWNLOAD_INTERSTITIAL -> adLoader?.showAd(activity)
            AdConstants.AD_ID_REOPEN_AD -> adLoader?.showAd(activity)
            else ->  {
                adLoader?.mOnLoadAdCallback?.onAdLoadFailed(AdConstants.ERROR_CODE_ACTIVITY_NOT_ACTIVE)
                release()
            }
        }
    }


    /**
     * 释放广告
     */
    fun release(){
        adLoader?.destroy()
        adLoader = null
    }



    // 根据类型获取可用的广告
    private fun getAvailableAdInfo(adContent: AdContent): AdInfo?{
        val adInfo = adContent.adInfo.firstOrNull { !TextUtils.isEmpty(it?.ad_position) }
        adInfo?.interval = adContent.interval
        return adInfo
    }

    private fun excLoadAd(
        activity: Activity,
        adType: Long,
        adName: String,
        adContent: AdContent,
        callback: OnLoadAdCallback
    ) {
        // 根据类型获取可用的广告
        val adInfo = getAvailableAdInfo(adContent)
        if (adInfo == null) {
            Log.e(AdConstants.TAG, "$adName -> CommonAdTools ->当前并没有配置 -> $adName")
            callback.onAdLoadFailed(AdConstants.ERROR_CODE_AD_NO_SETTING)
            return
        }
        // 判断时间间隔
        if (System.currentTimeMillis() < adInfo.showTime) {
            val time = adInfo.showTime - System.currentTimeMillis()
            Log.e(AdConstants.TAG, "$adName -> CommonAdTools -> 未到展示时间..." + Tools.getHMSTime(time))
            callback.onAdLoadFailed(AdConstants.ERROR_CODE_CAN_NOT_SHOW_TIME)
            return
        }

        // 根据广告获取对应的AdLoader
        adLoader = getAdLoader(adInfo)
        if (adLoader == null) {
            Log.e(AdConstants.TAG, "$adName CommonAdTools -> 找不到对应的AdLoader")
            callback.onAdLoadFailed(AdConstants.ERROR_CODE_AD_NO_LOADER)
            return
        }
        Log.e(AdConstants.TAG, "$adName CommonAdTools -> 执行广告加载...")
        // 加载广告
        adLoader?.loadAdNew(activity, adInfo, object : OnLoadAdCallback() {

            override fun onAdLoaded(ad: Any?, vararg tag: Int) {
                super.onAdLoaded(ad, *tag)
                Log.d(AdConstants.TAG, "$adName CommonAdTools -> onAdLoaded..." + adLoader?.isAdLoadSuccess())
                callback.onAdLoaded(ad)
            }

            override fun onAdLoadFailed(errorCode: Int) {
                super.onAdLoadFailed(errorCode)
                Log.d(AdConstants.TAG, "$adName CommonAdTools -> onAdLoadFailed -> $errorCode")
                // 判断是否有填充广告
                val count = adContent.adInfo?.count { !TextUtils.isEmpty(it.ad_position) } ?: 0
                if (count <= 1) { // 无填充广告
                    callback.onAdLoadFailed(errorCode)
                    if (adContent.adId != AdConstants.AD_ID_REOPEN_AD && adContent.adId != AdConstants.AD_ID_VIDEO_DETAIL_INTERSTITIAL) {
                        release()
                    }
                    return
                }
                // 有填充广告
                // 删除当前的广告，并从剩余的广告中获取可用加载广告的AdInfo
                adContent.adInfo?.remove(adInfo)
                // 继续请求广告
                excLoadAd(activity, adType, adName, adContent, callback)
            }

            override fun onUserEarnedReward(amount: Int) {
                super.onUserEarnedReward(amount)
                Log.d(AdConstants.TAG, "$adName CommonAdTools -> onUserEarnedReward...")
                callback.onUserEarnedReward(amount)
            }

            override fun onAdOpened() {
                super.onAdOpened()
                Log.d(AdConstants.TAG, "$adName CommonAdTools -> onAdOpened...")
                callback.onAdOpened()
            }

            override fun onAdClicked() {
                super.onAdClicked()
                Log.d(AdConstants.TAG, "$adName CommonAdTools -> onAdClicked...")
                callback.onAdClicked()
            }

            override fun onAdComplete() {
                super.onAdComplete()
                Log.d(AdConstants.TAG, "$adName CommonAdTools -> onAdComplete...")
                callback.onAdComplete()
                release()
                // 更新显示时间
                if (adInfo.interval <= 0) return
                RxUtils.doObservable {
                    val nextShowTime = System.currentTimeMillis() + adInfo.interval * 1000L
                    if (nextShowTime > 0) {
                        Log.d(AdConstants.TAG, "$adName  开始更新显示时间...${Tools.timeStamp2Date(nextShowTime)}")
                    }
                    adContent.adInfo?.forEach {
                        it?.showTime = nextShowTime
                    }
                    // 更新广告
                    AdRoomUtils.getInstance().adDao().insert(adContent)

                    if (AdUtils.debugModel) {
                        val time = AdRoomUtils.getInstance().adDao().query(adType)?.adInfo?.firstOrNull()?.showTime?:0
                        if (nextShowTime > 0) {
                            Log.d(AdConstants.TAG, "$adName  更新后的时间...${Tools.timeStamp2Date(time)}")
                        }
                    }
                    it.onNext(1)
                }
            }
        })
    }


    /**
     * 根据广告获取加载类
     */
    private fun getAdLoader(adInfo: AdInfo): BaseAdLoader? {
        return when (adInfo.ad_type) {
            AdConstants.ADTYPE_OPEN -> {
                when (adInfo.advertiser) {
                    AdConstants.ADVERTISER_ADMOB -> AdmobInterstitialAdUtils()
                    AdConstants.ADVERTISER_IRON_SOURCE -> ISInterstitialAdUtils()
                    else -> null
                }
            }

            AdConstants.ADTYPE_BANNER -> {
                when (adInfo.advertiser) {
                    AdConstants.ADVERTISER_ADMOB -> AdmobBannerAdUtils()
                    AdConstants.ADVERTISER_IRON_SOURCE -> ISBannerAdUtils()
                    else -> null
                }
            }

            AdConstants.ADTYPE_PAUSE_VIDEO, AdConstants.ADTYPE_INSTREAM_VIDEO -> {
                when (adInfo.advertiser) {
                    AdConstants.ADVERTISER_ADMOB -> AdmobBannerAdUtils()
                    AdConstants.ADVERTISER_IRON_SOURCE -> ISBannerAdUtils()
                    else -> null
                }
            }

            AdConstants.ADTYPE_INTERSTITIAL -> {
                when (adInfo.advertiser) {
                    AdConstants.ADVERTISER_ADMOB -> AdmobInterstitialAdUtils()
                    AdConstants.ADVERTISER_IRON_SOURCE -> ISInterstitialAdUtils()
                    else -> null
                }
            }

            AdConstants.ADTYPE_REWARDED -> {
                when (adInfo.advertiser) {
                    AdConstants.ADVERTISER_ADMOB -> AdmobRewardedAdUtils()
                    AdConstants.ADVERTISER_IRON_SOURCE -> ISRewardedAdUtils()
                    else -> null
                }
            }
            AdConstants.ADTYPE_SPLASH -> {
                when (adInfo.advertiser) {
                    AdConstants.ADVERTISER_ADMOB -> AdmobSplashAdUtils()
                    else -> null
                }
            }
            else -> null
        }
    }


}